package org.lwxyz.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * @description 日期处理工具类
 * @author yuwei
 * @version 1.0-SNAPSHOT
 * @date 2018/1/23
 */
public final class DateUtil {

    /**
     * 日志日期格式
     */
    private static final String LOG_SIMPLE_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /**
     * 日志日期格式，只含年、月、日
     */
    private static final String LOG_YEAR_MON_DAY_DAY_FORMAT = "yyyy-MM-dd";

    /**
     * 日志日期格式，年开始位置
     */
    private static final int LOG_DATE_YEAR_START_INDEX = 0;
    /**
     * 日志日期格式，年结束位置
     */
    private static final int LOG_DATE_YEAR_END_INDEX = 4;
    /**
     * 日志日期格式，月开始位置
     */
    private static final int LOG_DATE_MONTH_START_INDEX = 5;
    /**
     * 日志日期格式，月结束位置
     */
    private static final int LOG_DATE_MONTH_END_INDEX = 7;
    /**
     * 日志日期格式，日开始位置
     */
    private static final int LOG_DATE_DAY_START_INDEX = 8;
    /**
     * 日志日期格式，日结束位置
     */
    private static final int LOG_DATE_DAY_END_INDEX = 10;
    /**
     * 日志日期格式，时开始位置
     */
    private static final int LOG_DATE_HOUR_START_INDEX = 11;
    /**
     * 日志日期格式，时结束位置
     */
    private static final int LOG_DATE_HOUR_END_INDEX = 13;

    /**
     * 年、月、日、小时格式
     */
    private static final String YEAR_MON_DAY_HOUR_FORMAT = "yyyyMMddHH";
    /**
     * 年、月、日格式
     */
    private static final String YEAR_MON_DAY_FORMAT = "yyyyMMdd";
    /**
     * 年、月、日、时、分、秒格式
     */
    private static final String YEAR_MON_DAY_HOUR_MINITE_SECOND_FORMAT = "yyyyMMddHHmmss";
    /**
     * hadoop输出日志的日期格式
     */
    private static final String HADOOP_LOG_DATE_FORMAT = "yy/MM/dd HH:mm:ss";
    /**
     * 每天的毫秒数
     */
    private static final long MILLISECONDS_PER_DAY = 24L * 3600 * 1000;

    /**
     * 隐藏构造函数
     */
    private DateUtil() {
    }

    /**
     * 日志中的时间格式转Date
     *
     * @param dateStr 日期字符串
     * @return 日期
     * @throws ParseException 解析异常
     */
    public static Date logDateStrToDate(final String dateStr) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(LOG_SIMPLE_DATE_FORMAT, Locale.US);
        return sdf.parse(dateStr.trim());
    }

    /**
     * Date转日志中的时间格式
     *
     * @param date 略
     * @return 略
     */
    public static String dateToLogDateStr(final Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(LOG_SIMPLE_DATE_FORMAT, Locale.US);
        return sdf.format(date);
    }

    /**
     * Date转为年月日字符串
     *
     * @param date 略
     * @return 略
     */
    public static String dateToSimpleDateStr(final Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(YEAR_MON_DAY_FORMAT, Locale.US);
        return sdf.format(date);
    }

    /**
     * 年月日字符串转为Date
     *
     * @param dateStr 略
     * @return 略
     */
    public static Date dateToSimpleDateStr(final String dateStr) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(YEAR_MON_DAY_FORMAT, Locale.US);
        return sdf.parse(dateStr.trim());
    }

    /**
     * Date转为年月日时字符串
     *
     * @param date 略
     * @return 略
     */
    public static String dateToYearMonDayHourFormat(final Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(YEAR_MON_DAY_HOUR_FORMAT, Locale.US);
        return sdf.format(date);
    }

    /**
     * 日志中的时间格式转Date，只保留年月日
     *
     * @param dateStr 略
     * @return 略
     * @throws ParseException 略
     */
    public static Date logDateStrToDateOfDay(final String dateStr) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(LOG_YEAR_MON_DAY_DAY_FORMAT, Locale.US);
        return sdf.parse(dateStr.trim());
    }

    /**
     * 从日志中的日期中直接提取出年、月、日、时字符串
     * 日志中的日期格式为：2016-06-19 10:29:58
     *
     * @param dateStr 略
     * @return 略
     * @throws Exception 略
     */
    public static String getYearMonDayHourStrFromLogDateStr(final String dateStr) throws Exception {
        if (dateStr == null) {
            return "";
        }
        return new StringBuilder()
                .append(dateStr.substring(LOG_DATE_YEAR_START_INDEX, LOG_DATE_YEAR_END_INDEX))
                .append(dateStr.substring(LOG_DATE_MONTH_START_INDEX, LOG_DATE_MONTH_END_INDEX))
                .append(dateStr.substring(LOG_DATE_DAY_START_INDEX, LOG_DATE_DAY_END_INDEX))
                .append(dateStr.substring(LOG_DATE_HOUR_START_INDEX, LOG_DATE_HOUR_END_INDEX))
                .toString();
    }

    /**
     * "年月日时分秒"字符串转化成日期对象
     *
     * @param dateStr 略
     * @return 略
     * @throws ParseException 略
     */
    public static Date dateStrToDate(final String dateStr) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(YEAR_MON_DAY_HOUR_MINITE_SECOND_FORMAT, Locale.US);
        return sdf.parse(dateStr.trim());
    }

    /**
     * 比较两个时间戳，判断是否在day天内
     *
     * @param checkTimestamp    略
     * @param comparedTimestamp 略
     * @param days              略
     * @return 略
     */
    public static boolean inDays(final long checkTimestamp, final long comparedTimestamp, final int days) {
        return (checkTimestamp - comparedTimestamp) < days * MILLISECONDS_PER_DAY;
    }

    /**
     * hadoop任务日志中的时间格式转Date
     *
     * @param dateStr 略
     * @return 略
     * @throws ParseException 略
     */
    public static Date hadoopLogDateStrToDate(final String dateStr) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(HADOOP_LOG_DATE_FORMAT, Locale.US);
        return sdf.parse(dateStr.trim());
    }

    /**
     * 判断是否工作日
     *
     * @param date 日期
     * @return
     */
    public static boolean isWorkday(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        return !(dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY);
    }

    /**
     * 取当前时间判断是否工作日
     *
     * @return
     */
    public static boolean isWorkday() {
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        return !(dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY);
    }

    /**
     * 获取指定日期是星期几
     *
     * @param date
     * @return
     */
    public static int getDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 获取当前日期是星期几
     *
     * @return
     */
    public static int getDayOfWeek() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 获取日期的小时数
     *
     * @param date
     * @return
     */
    public static int getHourOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取当前时间的小时数
     *
     * @return
     */
    public static int getHourOfDay() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

}
